package com.sc.nft.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import com.sc.nft.dao.*;
import com.sc.nft.entity.*;
import com.sc.nft.enums.CollectionOnConsignEnum;
import com.sc.nft.enums.ConSignStatus;
import com.sc.nft.enums.DigitalMarketTypeEnum;
import com.sc.nft.enums.UserConsensusTypeEnums;
import com.sc.nft.exception.GlobalRunTimeException;
import com.sc.nft.pool.UserPool;
import com.sc.nft.service.UserConsensusService;
import com.sc.nft.sup.ErrorCode;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import com.sc.nft.service.CollectiveSalesService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalTime;
import java.util.List;

/**
 * 集售挂单表服务接口实现
 *
 * @author zxy
 * @since 2024-09-17 20:51:05
 * @description 由 Mybatisplus Code Generator 创建
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class CollectiveSalesServiceImpl implements CollectiveSalesService {
    private final CollectiveSalesDao collectiveSalesDao;
    private final CollectiveSalesConfigDao collectiveSalesConfigDao;
    private final UserCollectionDao userCollectionDao;
    private final DigitalCollectionDao digitalCollectionDao;
    private final UserCollectionConsensusDao userCollectionConsensusDao;
    private final ExitConsensusUserDao exitConsensusUserDao;
    private final UserConsensusService userConsensusService;
    private final FilterIncomeListDao filterIncomeListDao;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void into(Long id, Integer count, UserInfo userInfo) {
        CollectiveSalesConfig collectiveSalesConfig = collectiveSalesConfigDao.getById(id);
        Assert.isTrue(ObjectUtil.isNotNull(collectiveSalesConfig)&&collectiveSalesConfig.getStatus(),()->new GlobalRunTimeException("该藏品暂未开启集售"));
        DigitalCollection collection = digitalCollectionDao.getById(collectiveSalesConfig.getCollectionId());
        FilterIncomeList filterIncomeList = filterIncomeListDao.getIsTeamIncomeByUserId(userInfo.getId());
        Boolean isMarketAccount = ObjectUtil.isNotNull(filterIncomeList) ;
        if(isMarketAccount){
            if(filterIncomeList.getDaoId().longValue()==6L||filterIncomeList.getDaoId().longValue()==7L){

            }else {
                throw new GlobalRunTimeException("该账号禁止参与");
            }
        }else{
            if(collection.getCollectionType()== DigitalMarketTypeEnum.ECOLOGY){
                ExitConsensusUser exitConsensusUser = exitConsensusUserDao.getByUserId(userInfo.getId());
                if(ObjectUtil.isNotNull(exitConsensusUser)&&exitConsensusUser.getStatus()){
                    throw new GlobalRunTimeException("该藏品仅允许共识区用户集售");
                }else{
                    UserCollectionConsensus userConsensus = userCollectionConsensusDao.getBuyUserIdAndCollectionId(userInfo.getId(), collection.getId());
                    if(ObjectUtil.isNull(userConsensus)|| NumberUtil.isLess(userConsensus.getConsensusNum(), BigDecimal.valueOf(count))){
                        throw new GlobalRunTimeException("该生态共识度不足");
                    }
                }
                userConsensusService.adjustConsensusService(userInfo.getId(),collectiveSalesConfig.getCollectionId(),BigDecimal.valueOf(count).negate(), UserConsensusTypeEnums.COLLECTIVE_INTO,collection.getFirstTitle(),null);
            }
            if(collectiveSalesConfig.getIntoCollectionId()!=null){
                DigitalCollection need = digitalCollectionDao.getById(collectiveSalesConfig.getIntoCollectionId());
                Assert.isTrue(userCollectionDao.getCountByCollercitonIdAndUserId(userInfo.getId(),collectiveSalesConfig.getIntoCollectionId())>0,()-> new GlobalRunTimeException("未持有"+need.getFirstTitle()+"藏品，禁止投入"));
            }
        }
        Assert.notNull(collection,()->new GlobalRunTimeException(ErrorCode.COLLECTION_NOT_FOUND));
        Assert.isTrue((collectiveSalesDao.getCollectionOnConsignCount(collectiveSalesConfig.getCollectionId())+count)<=collectiveSalesConfig.getSumIntoLimit(),()-> new GlobalRunTimeException("投入数量超出活动上限"));
        LocalTime nowTime = LocalTime.now();
        DateTime dateTime = DateTime.of(nowTime.toString().substring(0, 8), "HH:mm:ss");
        Assert.isTrue(dateTime.isAfter(collectiveSalesConfig.getStartIntoTime())&&dateTime.isBefore(collectiveSalesConfig.getEndIntoTime()),()-> new GlobalRunTimeException("暂未达到投入时间"));
        List<UserCollection> userCollections = userCollectionDao.getUserCollectionListByCollectionIdAndUserIdAndSize(collectiveSalesConfig.getCollectionId(), userInfo.getId(), count);
        Assert.isTrue(userCollections.size()==count.intValue(),()-> new GlobalRunTimeException("可集售藏品数量不足"));

        DateTime today = DateTime.now();
        for (UserCollection userCollection : userCollections) {
            CollectiveSales collectiveSales = new CollectiveSales();
            collectiveSales.setCollectionId(collection.getId());
            collectiveSales.setCollectiveDate(today);
            collectiveSales.setOffSalesTime(DateUtil.endOfDay(today));
            collectiveSales.setUserCollectionId(userCollection.getId());
            collectiveSales.setUserId(userInfo.getId());
            collectiveSales.setStatus(ConSignStatus.ON_SALES);
            collectiveSales.setNumbering(userCollection.getNumbering());
            collectiveSales.insert();
            Assert.isTrue(userCollectionDao.setConsignStatusAndEq(userCollection.getId(), CollectionOnConsignEnum.ON_COLLECTIVE,CollectionOnConsignEnum.NORMAL),()->new GlobalRunTimeException("藏品状态更新失败"));

        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void revoke(Long id, Integer count, UserInfo userInfo) {
        List<CollectiveSales> userCollectionOnConsignList = collectiveSalesDao.getUserCollectionOnConsignListLimit(userInfo.getId(), id,count);
        Assert.isTrue(userCollectionOnConsignList.size()==count.intValue(),()->new GlobalRunTimeException("可撤销数量不足，请刷新后再试"));
        DigitalCollection collection = digitalCollectionDao.getEcologyCollectionById(id);
        if(ObjectUtil.isNotNull(collection)){
            userConsensusService.adjustConsensusService(userInfo.getId(),id,BigDecimal.valueOf(count), UserConsensusTypeEnums.COLLECTIVE_CANCEL,collection.getFirstTitle(),null);
        }

        for (CollectiveSales collectiveSales : userCollectionOnConsignList) {
            Assert.isTrue(userCollectionDao.setConsignStatusAndEq(collectiveSales.getUserCollectionId(), CollectionOnConsignEnum.NORMAL,CollectionOnConsignEnum.ON_COLLECTIVE),()->new GlobalRunTimeException("状态更新失败"));
            Assert.isTrue(collectiveSalesDao.updateStatusToCancel(collectiveSales.getId()),()->new GlobalRunTimeException("状态更新失败"));
        }
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void revokeOne(Long id,  UserInfo userInfo) {
        UserCollection userCollection = userCollectionDao.getById(id);
        Assert.isTrue(ObjectUtil.isNotNull(userCollection)&&userCollection.getUserId().longValue()==userInfo.getId().longValue(),()->new GlobalRunTimeException(ErrorCode.COLLECTION_NOT_FOUND));
        Assert.isTrue(userCollection.getOnConsign()==CollectionOnConsignEnum.ON_COLLECTIVE,()->new GlobalRunTimeException("藏品状态不正确，请刷新后再试"));
        CollectiveSales collectiveSales = collectiveSalesDao.getByUserCollectionId(userInfo.getId(), id);
        Assert.isTrue(ObjectUtil.isNotNull(collectiveSales),()->new GlobalRunTimeException("未找到集售记录"));
        DigitalCollection collection = digitalCollectionDao.getById(userCollection.getCollectionId());
        if(ObjectUtil.isNotNull(collection)&&collection.getCollectionType()==DigitalMarketTypeEnum.ECOLOGY){
            userConsensusService.adjustConsensusService(userInfo.getId(),collection.getId(),BigDecimal.ONE, UserConsensusTypeEnums.COLLECTIVE_CANCEL,collection.getFirstTitle(),null);
        }
            Assert.isTrue(userCollectionDao.setConsignStatusAndEq(collectiveSales.getUserCollectionId(), CollectionOnConsignEnum.NORMAL,CollectionOnConsignEnum.ON_COLLECTIVE),()->new GlobalRunTimeException("状态更新失败"));
            Assert.isTrue(collectiveSalesDao.updateStatusToCancel(collectiveSales.getId()),()->new GlobalRunTimeException("状态更新失败"));
    }



    @Override
    @Transactional(rollbackFor = Exception.class)
    public void autoCancel(CollectiveSales collectiveSales) {
        DigitalCollection collection = digitalCollectionDao.getEcologyCollectionById(collectiveSales.getCollectionId());
        if(ObjectUtil.isNotNull(collection)){
            userConsensusService.adjustConsensusService(collectiveSales.getUserId(),collection.getId(),BigDecimal.ONE, UserConsensusTypeEnums.COLLECTIVE_CANCEL,collection.getFirstTitle(),null);
        }
        Assert.isTrue(userCollectionDao.setConsignStatusAndEq(collectiveSales.getUserCollectionId(), CollectionOnConsignEnum.NORMAL,CollectionOnConsignEnum.ON_COLLECTIVE),()->new GlobalRunTimeException("状态更新失败"));
        Assert.isTrue(collectiveSalesDao.updateStatusToCancel(collectiveSales.getId()),()->new GlobalRunTimeException("状态更新失败"));
    }
}